package com.cheng.myrecyclerview.decoration;


import android.graphics.Rect;
import android.view.View;
import android.view.ViewGroup;

import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;

/**
 * 给 GridLayoutManager or StaggeredGridLayoutManager 设置间距，可设置去除首尾间距个数
 */

public class GridSpaceItemDecoration extends RecyclerView.ItemDecoration {

    /**
     * 每行个数
     */
    private int mSpanCount;
    /**
     * 间距
     */
    private int mSpacing;
    /**
     * 行距距
     */
    private int leading;
    /**
     * 是否有行距
     */
    private boolean isLeading = false;
    /**
     * 距屏幕周围是否也有间距
     */
    private boolean mIncludeEdge;

    /**
     * 头部 不显示间距的item个数
     */
    private int mStartFromSize;
    /**
     * 尾部 不显示间距的item个数 默认不处理最后一个item的间距
     */
    private int mEndFromSize = 1;

    /**
     * 首列item左边距
     */
    private int mLeft;
    /**
     * 尾列item左边距
     */
    private int mRight;
    /**
     * 列间距是否一样
     */
    private boolean isAverage = false;


    public GridSpaceItemDecoration(int spanCount, int spacing) {
        this(spanCount, spacing, true);
    }

    public GridSpaceItemDecoration(int spanCount, int spacing, int left, int right, boolean includeEdge, boolean isAverage) {
        this.mSpanCount = spanCount;
        this.mSpacing = spacing;
        this.mLeft = left;
        this.mRight = right;
        this.mIncludeEdge = includeEdge;
        this.isAverage = isAverage;
    }

    /**
     * @param spanCount   item 每行个数
     * @param spacing     item 间距
     * @param includeEdge item 距屏幕周围是否也有间距
     */
    public GridSpaceItemDecoration(int spanCount, int spacing, boolean includeEdge) {
        this.mSpanCount = spanCount;
        this.mSpacing = spacing;
        this.mIncludeEdge = includeEdge;
    }

    /**
     * @param spanCount   item 每行个数
     * @param spacing     item 间距
     * @param leading     item 行距
     * @param isLeading   item 是否行距不同
     * @param includeEdge item 距屏幕周围是否也有间距
     */
    public GridSpaceItemDecoration(int spanCount, int spacing, int leading, boolean isLeading, boolean includeEdge) {
        this.mSpanCount = spanCount;
        this.mSpacing = spacing;
        this.leading = leading;
        this.isLeading = isLeading;
        this.mIncludeEdge = includeEdge;
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        int lastPosition = state.getItemCount() - 1;
        int position = parent.getChildAdapterPosition(view);
        if (mStartFromSize <= position && position <= lastPosition - mEndFromSize) {

            // 减掉不设置间距的position
            position = position - mStartFromSize;
            int column = position % mSpanCount;

            // 瀑布流获取列方式不一样
            ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
            if (layoutParams instanceof StaggeredGridLayoutManager.LayoutParams) {
                column = ((StaggeredGridLayoutManager.LayoutParams) layoutParams).getSpanIndex();
            }

            if (mIncludeEdge) {
                /*
                 *示例：
                 * spacing = 10 ；spanCount = 3
                 * ---------10--------
                 * 10   3+7   6+4    10
                 * ---------10--------
                 * 10   3+7   6+4    10
                 * ---------10--------
                 */


                int left = mSpacing - column * mSpacing / mSpanCount;
                int right = (column + 1) * mSpacing / mSpanCount;

                if (isAverage) {
                    if (left == mSpacing) {
                        outRect.left = mLeft;
                        outRect.right = right;

                    } else if (right == mSpacing) {
                        outRect.left = left;
                        outRect.right = mRight;

                    } else {
                        outRect.left = left;
                        outRect.right = right;
                    }
                } else {
                    outRect.left = left;
                    outRect.right = right;
                }

                if (position < mSpanCount) {
                    if (isLeading) {
                        outRect.top = leading;
                    } else {
                        outRect.top = mSpacing;
                    }
                }
                if (isLeading) {
                    outRect.bottom = leading;
                } else {
                    outRect.bottom = mSpacing;
                }

            } else {
                /*
                 *示例：
                 * spacing = 10 ；spanCount = 3
                 * --------0--------
                 * 0   3+7   6+4    0
                 * -------10--------
                 * 0   3+7   6+4    0
                 * --------0--------
                 */
                outRect.left = column * mSpacing / mSpanCount;
                outRect.right = mSpacing - (column + 1) * mSpacing / mSpanCount;
                if (position >= mSpanCount) {
                    if (isLeading) {
                        outRect.top = leading;
                    } else {
                        outRect.top = mSpacing;
                    }
                }
            }
        }
    }

    private static final String TAG = "GridSpaceItemDecoration";

    /**
     * 设置从哪个位置 开始设置间距
     *
     * @param startFromSize 一般为HeaderView的个数 + 刷新布局(不一定设置)
     */
    public GridSpaceItemDecoration setStartFrom(int startFromSize) {
        this.mStartFromSize = startFromSize;
        return this;
    }

    /**
     * 设置从哪个位置 结束设置间距。默认为1，默认用户设置了上拉加载
     *
     * @param endFromSize 一般为FooterView的个数 + 加载更多布局(不一定设置)
     */
    public GridSpaceItemDecoration setEndFromSize(int endFromSize) {
        this.mEndFromSize = endFromSize;
        return this;
    }

    /**
     * 设置从哪个位置 结束设置间距
     *
     * @param startFromSize 一般为HeaderView的个数 + 刷新布局(不一定设置)
     * @param endFromSize   默认为1，一般为FooterView的个数 + 加载更多布局(不一定设置)
     */
    public GridSpaceItemDecoration setNoShowSpace(int startFromSize, int endFromSize) {
        this.mStartFromSize = startFromSize;
        this.mEndFromSize = endFromSize;
        return this;
    }
}
